package com.cdhkppm.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;


/**
 * @author yfq
 * @apiNote
 */
public class DateUtil {

    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


    // 默认每天工作小时数
    private static final int WORK_HOURS_PER_DAY = 8;
    // 每天工作毫秒数（8小时 * 60分钟 * 60秒 * 1000毫秒）
    private static final long MILLISECONDS_PER_WORKDAY = WORK_HOURS_PER_DAY * 60 * 60 * 1000;

    public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final LocalDate EXCEL_START_DATE = LocalDate.of(1899, 12, 30); // Excel 起点

    public static String formatExcelDate(String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }

        try {
            value = value.trim();

            // Excel 数字日期（允许小数，代表时间）
            if (value.matches("\\d+(\\.\\d+)?")) {
                double days = Double.parseDouble(value);

                long wholeDays = (long) days;
                double fractional = days - wholeDays;

                // Excel 小数部分表示一天中的时间（fraction * 24h）
                long secondsInDay = Math.round(fractional * 24 * 60 * 60);

                LocalDateTime dateTime = EXCEL_START_DATE.plusDays(wholeDays).atStartOfDay().plusSeconds(secondsInDay);
                return dateTime.format(FORMATTER);
            }

            // 尝试 yyyy-MM-dd HH:mm:ss
            try {
                LocalDateTime dateTime = LocalDateTime.parse(value, FORMATTER);
                return dateTime.format(FORMATTER);
            } catch (Exception ignored) {}

            // 尝试 yyyy-MM-dd
            try {
                LocalDate date = LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                return date.atStartOfDay().format(FORMATTER);
            } catch (Exception ignored) {}

            // 尝试 yyyy/MM/dd
            try {
                LocalDate date = LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
                return date.atStartOfDay().format(FORMATTER);
            } catch (Exception ignored) {}

            // 如果全都不行，直接返回原字符串
            return value;
        } catch (Exception e) {
            return value;
        }
    }
    public boolean isWeekend(LocalDate date) {
        DayOfWeek day = date.getDayOfWeek();
        return day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY;
    }
    public static LocalDateTime calculateLateStartFromMillis(LocalDateTime lateFinishTime, long durationMillis) {
        final long MILLIS_PER_WORK_DAY = 28800000L; // 8小时/天
        int workDays = durationMillis > 0 ? (int) (durationMillis / MILLIS_PER_WORK_DAY) : 0;

        if (workDays == 0) {
            return lateFinishTime.with(LocalTime.MIN);
        }

        // 关键修正：判断结束日期是否为工作日，若是则先扣1天工期（当天计入）
        DayOfWeek finishDay = lateFinishTime.getDayOfWeek();
        if (finishDay != DayOfWeek.SATURDAY && finishDay != DayOfWeek.SUNDAY) {
            workDays--; // 结束日是工作日，已算1天，剩余天数减1
        }

        // 从结束日的前一天开始倒推剩余天数
        LocalDateTime current = lateFinishTime.minusDays(1);
        int remainingDays = workDays;

        while (remainingDays > 0) {
            current = current.minusDays(1);
            DayOfWeek day = current.getDayOfWeek();
            if (day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY) {
                remainingDays--;
            }
        }

        return current.with(LocalTime.MIN);
    }


    public static String formatLocalDateTime(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return dateTime.format(formatter);
    }

    public static LocalDate adjustToNextWorkday(LocalDate date) {
        DayOfWeek day = date.getDayOfWeek();
        if (day == DayOfWeek.SATURDAY) {
            return date.plusDays(2);
        } else if (day == DayOfWeek.SUNDAY) {
            return date.plusDays(1);
        }
        return date; // 工作日不调整

    }

    public static String getProjectEndDateWithTime(String baseDateStr) {
        // 1. 定义日期格式（复用避免重复创建）
        SimpleDateFormat baseDateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 输入日期格式
        SimpleDateFormat endTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 输出目标格式
        baseDateFormat.setLenient(false); // 严格校验日期格式，避免2025-13-01等无效日期

        // 2. 解析输入的日期字符串
        Date baseDate;
        try {
            baseDate = baseDateFormat.parse(baseDateStr);
        } catch (ParseException e) {
            // 日期格式无效（如非yyyy-MM-dd格式、无效日期）
            return null;
        }

        // 3. 转换为Calendar，方便处理星期和时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(baseDate);

        // 4. 检查是否为周末（周六：Calendar.SATURDAY=7，周日：Calendar.SUNDAY=1）
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == Calendar.SATURDAY) {
            // 周六：加2天到下周一
            calendar.add(Calendar.DATE, 2);
        } else if (dayOfWeek == Calendar.SUNDAY) {
            // 周日：加1天到下周一
            calendar.add(Calendar.DATE, 1);
        }
        // 非周末：不调整日期

        // 5. 设置时间为23:59:59
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0); // 清除毫秒，避免格式问题

        // 6. 格式化并返回
        return endTimeFormat.format(calendar.getTime());
    }

    public static long calculateWorkdayDuration(String startDateStr, String endDateStr) {
        LocalDateTime startDateTime = LocalDateTime.parse(startDateStr, DATE_TIME_FORMATTER);
        LocalDateTime endDateTime = LocalDateTime.parse(endDateStr, DATE_TIME_FORMATTER);
        return calculateWorkdayDuration(startDateTime, endDateTime);
    }

    public static long calculateWorkdayDuration(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        // 开始时间晚于结束时间，返回0
        if (startDateTime.isAfter(endDateTime)) {
            return 0;
        }

        // 计算开始日期和结束日期
        LocalDate startDate = startDateTime.toLocalDate();
        LocalDate endDate = endDateTime.toLocalDate();

        // 计算总天数（包含开始和结束日期）
        long totalDays = ChronoUnit.DAYS.between(startDate, endDate) + 1;

        // 如果总天数为1天，直接计算当天的工作时间
        if (totalDays == 1) {
            return isWeekday(startDate) ? MILLISECONDS_PER_WORKDAY : 0;
        }

        // 计算工作日数量
        long workdays = 0;
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            if (isWeekday(currentDate)) {
                workdays++;
            }
            currentDate = currentDate.plusDays(1);
        }

        // 总工作日毫秒数 = 工作日天数+ * 每天毫秒数
        return workdays * MILLISECONDS_PER_WORKDAY;
    }

    /**
     * 判断是否为工作日（周一至周五）
     */
    private static boolean isWeekday(LocalDate date) {
        DayOfWeek day = date.getDayOfWeek();
        return day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY;
    }
}
